﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Threading;
using System.Windows.Media.Imaging;

using System.Windows.Media.Effects;

namespace GameEngine
{
    public class GameObject
    {
        /// <summary>
        ///     ID increases for every GameObject created.
        /// </summary>
        protected static int _ID = 0;

        /// <summary>
        ///     ID of the GameObject-unique for every object.
        /// </summary>
        protected int _id;
        /// <summary>
        ///     Gets the id of the object.
        /// </summary>
        public int ID
        {
            get
            {
                return _id;
            }
        }
        
        /// <summary>
        ///     Position of this Object in pixels on tile(on which pixel of the tile it "sits").
        /// </summary>
        public IntPoint Position { get; set; }
        /// <summary>
        ///     Tile on which the object "sits".
        /// </summary>
        public IntPoint TilePosition { get; set; }
        /// <summary>
        ///     True if the player can walk trough the object.
        /// </summary>
        public bool Passable { get; set; }
        /// <summary>
        ///     True if the player can fly trough the object.
        /// </summary>
        public bool FlyPassable { get; set; }
        /// <summary>
        ///     Size of the object.
        /// </summary>
        //public IntSize _size { get; set; }

        /// <summary>
        ///     Visual representation of this object-animated objects use this when not moving.
        /// </summary>
        protected WriteableBitmap _visual;
        /// <summary>
        ///     Visual representation of this object to be rendered.
        /// </summary>
        protected WriteableBitmap _renderVisual;
        /// <summary>
        ///     Effect applied to this GameObject.
        /// </summary>
        protected Effect _effect = null;
        /// <summary>
        ///     Gets the id of the object.
        /// </summary>
        public Effect Effect
        {
            set
            {
                _effect = value;
            }
        }


        /// <summary>
        ///     Constructs a GameObject and sets a unique id for it.
        /// </summary>
        public GameObject()
        {
            _id = GetNextID();
        }


        /// <summary>
        ///     Returns the next ID.
        /// </summary>
        /// <returns></returns>
        protected int GetNextID()
        {
            return ++_ID;
        }


        /// <summary>
        ///     Sets the visual for the GameObject. Animated objects use this when not moving.
        /// </summary>
        /// <param name="imagePath">Path to the image file.</param>
        public void SetVisual(string imagePath)
        {
            //creates a new image holder
            Image image = new Image();
            //hides the image - we don't need to see it
            image.Visibility = Visibility.Collapsed;
            //and adds it to the visual tree so we can use the imageopened event
            (GameEngine.App.Current.RootVisual as MainPage).LayoutRoot.Children.Add(image);

            //set up the handler
            image.ImageOpened += new EventHandler<RoutedEventArgs>(LoadVisual);

            //set the image's source
            image.Source = new BitmapImage(new Uri(imagePath, UriKind.RelativeOrAbsolute));
        }


        /// <summary>
        ///     Loads the image into the internal bitmap.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void LoadVisual(object sender, RoutedEventArgs e)
        {
            Image image = (sender as Image);

            this._visual = new WriteableBitmap((int)image.ActualWidth, (int)image.ActualHeight);

            this._visual.Render(image, null);
            this._visual.Invalidate();
            this._renderVisual = _visual;

            //removes the image from the visual tree-we do not need it anymore
            (GameEngine.App.Current.RootVisual as MainPage).LayoutRoot.Children.Remove(image);
        }


        /// <summary>
        ///     Updates the visual representation of GameObject.
        /// </summary>
        /// <returns>Bitmap representing the updated visual.</returns>
        public virtual WriteableBitmap Update()
        {
            if (this._effect != null)
            {
                this._renderVisual = EffectHelper.ApplyEffect(this._renderVisual, this._effect);
            }

            return this._renderVisual;
        }
    }
}
